﻿using System;
using System.Linq;
using System.Net.Http;
using System.Windows.Forms;
using Eventless;
using Eventless.WinForms;

namespace NoteTaker
{
    public partial class NotesForm : Form
    {
        private readonly WriteableList<Note> _notes = new WriteableList<Note>();

        public NotesForm()
        {
            InitializeComponent();

            // For each each note, make a CheckedListBoxItem
            checkedListBoxNotes.Items().BindTo(_notes, note =>
                {
                    var item = new CheckedListBoxItem();

                    // Bind properties accordingly
                    item.Text.BindTo(note.Text);
                    item.IsChecked.BindTo(note.IsSelected);

                    return item;
                });

            // Add button only enabled if text box is non-empty
            buttonAdd.IsEnabled().BindTo(() => textBoxNewNote.Text().Value.Length != 0);
            buttonAdd.Click += (s, ev) =>
            {
                _notes.Add(new Note { Text = { Value = textBoxNewNote.Text } });
                textBoxNewNote.Text = string.Empty;
                textBoxNewNote.Focus();
            };

            // list of currently selected notes (important: ToList to avoid lazy evaluation)
            var selectedNotes = Computed.From(() => _notes.Where(n => n.IsSelected.Value).ToList());

            // Two-way binding, 
            checkBoxAllNotes.CheckState().BindTo(Computed.From(

                // getter: depends on how many of the notes are selected
                () => selectedNotes.Value.Count == 0
                        ? CheckState.Unchecked
                        : selectedNotes.Value.Count == _notes.Count
                            ? CheckState.Checked 
                            : CheckState.Indeterminate,
                
                // setter: broadcasts new state to all notes
                state =>
                    {
                        // only pay attention when setting to a definite state
                        if (state == CheckState.Indeterminate) 
                            return;

                        foreach (var note in _notes)
                            note.IsSelected.Value = state == CheckState.Checked;
                    }));

            checkBoxAllNotes.IsEnabled().BindTo(() => _notes.Count != 0);

            // Delete button only enabled if selection is non-empty
            buttonDelete.IsEnabled().BindTo(() => selectedNotes.Value.Count != 0);
            buttonDelete.Click += (s, ev) => _notes.RemoveAll(selectedNotes.Value);

            // Second example: compute a Uri object from the string
            var uri = Computed.From(() =>
                {
                    Uri result;
                    Uri.TryCreate(textBoxUrl.Text().Value, UriKind.Absolute, out result);
                    return result;
                });

            // Compute a Task<string> from the Uri (if any) 
            var get = Computed.From(() => uri.Value == null 
                ? null
                : new HttpClient().GetStringAsync(uri.Value));

            // Convert to a plain string (substitute empty string if no good response)
            var response = get.FromAsync(string.Empty);

            textBoxWebResponse.Text().BindTo(response);
        }
    }
}